#!/usr/bin/env python
from os import path
import sys

try:
    import pygtk
    pygtk.require("2.0")
except:
    pass
try:
    import gtk, gobject
    import gtk.glade
except:
    sys.exit(1)
    
path_list = ('/usr/share/sms-middleware/gui', 'gui', )

for dir_path in path_list:
    if path.exists(dir_path):
        GUI_DIR = dir_path
        APP_DIR, tail = path.split(dir_path)
        sys.path.insert(0, APP_DIR)
        break
else:
    raise Exception("No gui data directory found in %s" % path_list)

from plugin_factory import PluginFactory
from dbus_parser import DBusObject

GOVERNOR_GLADE_FILE = path.join(GUI_DIR, 'governor.glade')
PLUGINS_GLADE_FILE = path.join(GUI_DIR, 'plugins.glade')
INTROSPECTION_GLADE_FILE = path.join(GUI_DIR, 'introspection.glade')
        

class SMSMiddlewareGUI:
    
    def __init__(self):
        self.wTree = gtk.glade.XML(GOVERNOR_GLADE_FILE)
        self.wTree.signal_autoconnect({
            "introspect_button_clicked_cb": self.introspect_button_clicked_cb,
            "plugins_button_clicked_cb": self.plugins_button_clicked_cb,
            "status_button_clicked_cb" : self.status_button_clicked_cb,
            "exit_button_clicked_cb" : lambda widget: gtk.main_quit(),
            "on_MainWindow_destroy" : gtk.main_quit
        })

    def introspect_button_clicked_cb(self, widget):
        try:
            introspection_pane.show()
        except:
            introspection_pane = IntrospectionGUI(logger)
            introspection_pane.show()

    def plugins_button_clicked_cb(self, widget):
        plugins_pane.show()

    def status_button_clicked_cb(self, widget):
        self.filew = gtk.FileSelection("File selection")
        self.filew.connect("destroy", lambda w: self.filew.hide())
        self.filew.ok_button.connect("clicked", self.file_ok_sel)
        self.filew.cancel_button.connect("clicked", lambda w: self.filew.hide())
        self.filew.show()
        
    def file_ok_sel(self, widget):
        plugin_filename = self.filew.get_filename()
        plugin_name = plugins_pane.p_factory.install(plugin_filename)
        
        dialog = gtk.Dialog(title='Installer notification', parent=self.filew, flags=gtk.DIALOG_DESTROY_WITH_PARENT)
        button = gtk.Button(label='OK')
        button.connect("clicked", self.file_dialog_ok_sel_close)
        dialog.action_area.pack_start(button, True, True, 0)
        button.show()
        label = gtk.Label('Plugin %s installed' % (plugin_name))
        dialog.vbox.pack_start(label, True, True, 0)
        label.show()
        dialog.show()

    def file_dialog_ok_sel_close(self, widget):
        widget.parent.parent.parent.hide()
        self.filew.hide()
        self.filew = None


class PluginsGUI:
    
    def __init__(self, p_factory):
        self.p_factory = p_factory
        self.wTree = gtk.glade.XML(PLUGINS_GLADE_FILE)
        self.wTree.signal_autoconnect({
            'ok_button_clicked_cb':lambda widget: self.hide(),
            'on_MainWindow_destroy':lambda widget: gtk.main_quit()
        })
        
        self.treeview = self.wTree.get_widget('treeview')
        self.pane = self.wTree.get_widget('PluginsGTK')
        
        self.model = gtk.ListStore(gobject.TYPE_STRING,
                              gobject.TYPE_BOOLEAN)
        """
        for item in self.p_factory.active_plugins.values():
            self.model.append([item['name'], True])
        
        for item in self.p_factory.inactive_plugins.values():
            self.model.append([item['name'], False])
        """ 
        #gtk.TreeView.
        
        self.treeview.set_model(self.model)
        self.renderer = gtk.CellRendererText()
        #self.renderer.set_property( 'editable', True )
        #self.renderer.connect( 'edited', self.col0_edited_cb, model )

        # The toggle cellrenderer is setup and we allow it to be
        # changed (toggled) by the user.
        self.renderer1 = gtk.CellRendererToggle()
        self.renderer1.set_property('activatable', True)
        self.renderer1.connect( 'toggled', self.col1_toggled_cb, self.model )
		
        # Connect column0 of the display with column 0 in our list model
        # The renderer will then display whatever is in column 0 of
        # our model .
        self.column0 = gtk.TreeViewColumn("Plugin name", self.renderer, text=0)
        self.column0.set_sort_column_id(0)
		
        # The columns active state is attached to the second column
        # in the model.  So when the model says True then the button
        # will show as active e.g on.
        self.column1 = gtk.TreeViewColumn("Running", self.renderer1 )
        self.column1.add_attribute( self.renderer1, "active", 1)
        self.column1.set_sort_column_id(1)
        self.treeview.append_column( self.column0 )
        self.treeview.append_column( self.column1 )

    def show(self):
        self.p_factory.scan_for_plugins()
        self.model.clear()
        
        for item in self.p_factory.active_plugins.values():
            self.model.append([item['name'], True])
        
        for item in self.p_factory.inactive_plugins.values():
            self.model.append([item['name'], False])
            
        self.pane.show()
        
    def hide(self):
        self.pane.hide()
        
    def col0_edited_cb( self, cell, path, new_text, model ):
        """
        Called when a text cell is edited.  It puts the new text
        in the model so that it is displayed properly.
        """
        print "Change '%s' to '%s'" % (model[path][0], new_text)
        model[path][0] = new_text
        return
    
    def col1_toggled_cb( self, cell, path, model ):
        """
        Sets the toggled state on the toggle button to true or false.
        """
        model[path][1] = not model[path][1]
        if model[path][1]: # plugin is active
            for method in self.p_factory.inactive_plugins.keys():
                if self.p_factory.inactive_plugins[method]['name'] == model[path][0]:
                    self.p_factory.activate(method)

        else: # plugin is inactive
            for method in self.p_factory.active_plugins.keys():
                if self.p_factory.active_plugins[method]['name'] == model[path][0]:
                    self.p_factory.deactivate(method)
            
        return
"""
ifaces = {'/obj/device/sms':
    {'interface':None, 
     'method_list':[
         {'method':'send_sms','signature':'(int, str)'},
         {'method':'receive_sms','signature':'(int)'},
         {'method':'backlight_on','signature':'()'},
          ]
     },
    }
"""
    
class IntrospectionGUI:

    def show(self):
        self.pane.show()
        
    def hide(self):
        self.pane.hide()
    
    def __init__(self, logger):
        self.wTree = gtk.glade.XML(INTROSPECTION_GLADE_FILE)
        self.wTree.signal_autoconnect({ 
            'ok_button_clicked_cb':lambda widget: self.hide(),
            'on_MainWindow_destroy':lambda widget: gtk.main_quit()
        })
        
        self.treeview = self.wTree.get_widget('treeview')
        self.pane = self.wTree.get_widget('IntrospectionGTK')
        
        model = gtk.TreeStore(gobject.TYPE_STRING,
                              gobject.TYPE_STRING,)
        
        dbus_object = DBusObject(logger)
        dbus_object.initialize()
        ifaces = dbus_object.generate_gui_ifaces()
        if not ifaces:
            ifaces = {'No dbus':
                {'interface':None, 
                 'method_list':[]
                 },
            }
            
        for item in ifaces.keys():
            parent = model.append(None, (item, None))
            for kids in ifaces[item]['method_list']:
                model.append(parent, (kids['method'], kids['signature']))

        self.treeview.set_model(model)
        self.renderer = gtk.CellRendererText()

        self.column0 = gtk.TreeViewColumn("Method name", self.renderer, text=0)
        self.column0.set_sort_column_id(0)
		
        self.column1 = gtk.TreeViewColumn("Parameters", self.renderer, text=1)
        self.column1.set_sort_column_id(1)
        
        self.treeview.append_column(self.column0)
        self.treeview.append_column(self.column1)


if __name__ == "__main__":
    from loggers import loggers
    logger = loggers('smg', 'smg.log', False, False)
    
    main_pane = SMSMiddlewareGUI()
    p_factory = PluginFactory(logger)
    plugins_pane = PluginsGUI(p_factory)
    
    #exit(0) # for time tests
    gtk.main()

